package com.framework.core.minio;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.framework.core.exception.CustomException;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

/**
 * MinIO文件存储策略
 *
 * @author Kevin
 */
@Component
@Slf4j
@AllArgsConstructor
public class MinioUtil {

    /**
     * 默认大小 50M
     */
    private static final long DEFAULT_FILE_MAX_SIZE = 50 * 1024 * 1024;
    private MinioClient minioClient;
    private MinioProperties minioProperties;

    public void checkFile(MultipartFile file) {
        if (file.getSize() > DEFAULT_FILE_MAX_SIZE) {
            throw new CustomException(String.format("文件超过最大限制，最大%sM", DEFAULT_FILE_MAX_SIZE / 1024 / 1024));
        }
    }

    public String getFilepath(MultipartFile file, String bizPath) throws IOException {
        String extName = FileUtil.extName(file.getOriginalFilename());
        if (StrUtil.isBlank(extName)) {
            extName = FileTypeUtil.getType(file.getInputStream());
        }
        String filename = IdUtil.fastSimpleUUID() + "." + extName;
        String filepath = "/" + bizPath + "/" + DateUtil.today() + "/" + filename;
        return filepath;
    }

    public String upload(MultipartFile file, String bizPath) throws IOException {
        // 校验文件
        this.checkFile(file);
        String filepath = this.getFilepath(file, bizPath);
        log.info("上传文件原始名称：{}", file.getOriginalFilename());
        log.info("上传文件路径：{}", filepath);
        try {
            boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(minioProperties.getBucketName()).build());
            if (!exists) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(minioProperties.getBucketName()).build());
            }
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .bucket(minioProperties.getBucketName())
                    .object(filepath.substring(1))
                    .contentType(MediaType.APPLICATION_OCTET_STREAM_VALUE)
                    .stream(file.getInputStream(), file.getInputStream().available(), -1).build();
            minioClient.putObject(putObjectArgs);
        } catch (Exception e) {
            log.error("上传文件失败，{}", e.getMessage());
            throw new CustomException("上传文件失败，" + e.getMessage());
        }
        String url = minioProperties.getEndpoint() + "/" + minioProperties.getBucketName() + filepath;
        log.info("上传文件URL：{}", url);
        return url;
    }
}
